/**
 * @file socket_client.h
 * @author fwy (2643660853@qq.com)
 * @brief 客户端套接字类
 * @version 0.2
 * @date 2025-08-17
 *
 * @copyright Copyright (c) 2025
 *
 */

#pragma once

#include <iostream>
#include <string>
#include <thread>
#include <functional>
#include <mutex>
#include <atomic>
#include <vector>
#include <arpa/inet.h>
#include <unistd.h>
#include <chrono>

class SocketClient
{
public:
    using MessageCallback = std::function<void(const std::string &message)>;
    using ConnectionCallback = std::function<void(bool connected)>;

    SocketClient();
    ~SocketClient();

    // 连接到服务器
    bool connect(const std::string &server_ip, int server_port, const std::string &client_id = "client");

    // 发送消息到服务器
    bool sendMessage(const std::string &message);

    // 发送客户端标识
    bool sendIdentity();

    // 设置接收消息的回调
    void setMessageCallback(const MessageCallback &callback) { message_callback_ = callback; }

    // 设置连接状态变化的回调
    void setConnectionCallback(const ConnectionCallback &callback) { connection_callback_ = callback; }

    // 获取客户端ID
    std::string getClientId() const { return client_id_; }

    // 设置客户端ID
    void setClientId(const std::string &client_id);

    // 检查是否已连接
    bool isConnected() const { return socket_fd_ != -1 && connected_; }

    // 设置自动重连选项
    void setAutoReconnect(bool enable, int max_attempts = -1, int initial_delay_ms = 1000, int max_delay_ms = 30000);

    // 尝试重新连接
    bool reconnect();

    // 断开连接
    void close();

private:
    int socket_fd_ = -1;
    std::string client_id_;
    std::string server_ip_;
    int server_port_ = 0;
    std::atomic<bool> running_{false};
    std::atomic<bool> connected_{false};
    std::thread receive_thread_;
    std::thread reconnect_thread_;
    MessageCallback message_callback_ = nullptr;
    ConnectionCallback connection_callback_ = nullptr;
    std::mutex mutex_;

    // 重连相关配置
    bool auto_reconnect_ = false;
    int reconnect_attempts_ = 0;
    int max_reconnect_attempts_ = -1;    // -1表示无限重试
    int initial_reconnect_delay_ = 1000; // 毫秒
    int current_reconnect_delay_ = 1000; // 毫秒
    int max_reconnect_delay_ = 30000;    // 毫秒
    std::atomic<bool> reconnecting_{false};

    // 消息接收线程
    void receiveThread();

    // 重连线程
    void reconnectThread();

    // 重置重连延迟
    void resetReconnectDelay();

    // 增加重连延迟(指数退避)
    void increaseReconnectDelay();

    // 通知连接状态改变
    void notifyConnectionChange(bool connected);
};